﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Swift;
using SCM;
using System.Collections;
using Swift.Math;

/// <summary>
/// 客户端指引用
/// </summary>
public class GuideManager : Component
{
    static GuideManager()
    {
        Room4Client.OnBattleBegin += (r, isReplay) =>
        {
            if (isReplay)
                return;

            CreateGuide(r, "Guide_" + r.Lv.LevelID, r.Lv.LevelID);
        };

        Room4Client.OnBattleEnd += (r, winner, isReplay) =>
        {
            Clear();
        };

        GameCore.Instance.OnMainConnectionDisconnected += (conn, reason) =>
        {
            Clear();
        };
    }

    static void Clear()
    {
        var cm = GameCore.Instance.Get<CoroutineManager>();
        foreach (var g in gs.ValueArray)
            cm.Stop(g);

        gs.Clear();
        UIManager.Instance.Guide.HideAllHints();
    }

    static StableDictionary<string, ICoroutine> gs = new StableDictionary<string, ICoroutine>();
    public static void CreateGuide(Room4Client r, string id, string type)
    {
        switch (type)
        {
            case "PVE001":
                gs[type] = GameCore.Instance.Get<CoroutineManager>().Start(PVE001GuideImpl(r));
                break;
            case "PVE002":
                gs[type] = GameCore.Instance.Get<CoroutineManager>().Start(PVE002GuideImpl(r));
                break;
            case "PVE003":
                gs[type] = GameCore.Instance.Get<CoroutineManager>().Start(PVE003GuideImpl(r));
                break;
        }
    }

    // PVE001 基本建造教学
    static IEnumerator PVE001GuideImpl(Room4Client r)
    {
        var g = UIManager.Instance.Guide;

        yield return new TimeWaiter(1000);

        var cc = r.GetMyFirstUnitByType("CommanderCenter");
        g.ToClick(UIManager.Instance.World2UI(cc.Pos), "帝国部队正在攻击我们的<u>基地</u>");
        yield return new TimeWaiter(2000);

        // 提示保护基地
        var sds = r.GetUnitsInCircleArea(cc.Pos, 200, (u) => u.Player == 1);
        if (sds.Length > 0)
        {
            var enemy = sds[0];
            g.ToClick(UIManager.Instance.World2UI(enemy.Pos), "<op>点击</op>移动部队，消灭帝国士兵");
            yield return new TimeWaiter(2000);
            // 等待移动指令
            yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("Soldier").MovePath.Count > 0);
            g.HideAllHints();

            // 等到枪兵被消灭
            yield return new ConditionWaiter(() => enemy.Hp <= 0);
        }

        yield return new TimeWaiter(1000);

        // 提示建造兵营
        g.ToPress(UIManager.Instance.World2UI(cc.Pos + new Vec2(-80, -50)), "<op>长按</op>:建造<u>兵营</u>，生产更多士兵");
        // 等待开始建造兵营
        yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("Barrack") != null);
        g.HideAllHints();

        // 提示建造矿机
        yield return new TimeWaiter(2000);
        g.ToClick(UIManager.Instance.World2UI(cc.Pos), "建造<u>矿机</u>可以加速资源生产");
        yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("CCAcc") != null);
        g.HideAllHints();

        // 等待兵营建造完成
        yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("Barrack") != null &&
            r.GetMyFirstUnitByType("Barrack").BuildingCompleted);

        // 提示建造枪兵
        var brk = r.GetMyFirstUnitByType("Barrack");
        g.ToClick(UIManager.Instance.World2UI(brk.Pos), "从兵营中生产更多士兵");
        // 等待建造队列
        yield return new ConditionWaiter(() => brk.UnitCosntructingWaitingList.Count > 0);
        g.HideAllHints();

        var sdCnt = r.GetAllMyUnits((u) => !u.cfg.IsBuilding).Length;
        yield return new ConditionWaiter(() => r.GetAllMyUnits((u) => !u.cfg.IsBuilding).Length > sdCnt);
        g.ToClick(UIManager.Instance.World2UI(brk.Pos), "建造更多士兵");
        yield return new TimeWaiter(2000);
        g.HideAllHints();

        // 等待 5 个任意战斗单位
        yield return new ConditionWaiter(() => r.GetAllMyUnits((u) => !u.cfg.IsBuilding).Length >= 5);
        var cc1Arr = r.GetAllUnitsByPlayer(1, (u) => u.UnitType == "CommanderCenter");
        if (cc1Arr.Length > 0)
        {
            var cc1 = cc1Arr[0];

            // 提示攻击对方基地
            g.ToClick(UIManager.Instance.World2UI(cc1.Pos), "拆毁对方<u>基地</u>，获取战斗胜利");
            var sd = r.GetAllMyUnits((u) => !u.cfg.IsBuilding)[0];
            yield return new TimeWaiter(2000);
            // 等待用户指挥进攻
            yield return new ConditionWaiter(() => sd.MovePath.Count > 0 &&
                (sd.MovePath[sd.MovePath.Count - 1] - cc1.Pos).Length < 100);
            g.HideAllHints();
        }
    }

    // PVE002 拖动操作教学
    static IEnumerator PVE002GuideImpl(Room4Client r)
    {
        var g = UIManager.Instance.Guide;

        yield return new ConditionWaiter(() =>
        {
            var b = r.GetMyFirstUnitByType("Bunker");
            return b != null && b.Hp >= b.cfg.MaxHp * 0.75f;
        });
        var bck = r.GetMyFirstUnitByType("Bunker");
        g.ToClick(UIManager.Instance.World2UI(bck.Pos), "<u>炮台</u>是高效的防御建筑");
        yield return new TimeWaiter(3000);
        g.HideAllHints();

        // 等待第一批炮台建好，提示建造新炮台
        yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("Bunker").BuildingCompleted);
        g.ToPress(UIManager.Instance.World2UI(bck.Pos + new Vec2(0, 10)), "<op>长按</op>:建造更多<u>小炮台</u>以加强防御");
        yield return new ConditionWaiter(() =>
        {
            var bcks = r.GetMyUnitsByType("Bunker");
            foreach (var b in bcks)
            {
                if (!b.BuildingCompleted)
                    return true;
            }

            return false;
        });
        g.HideAllHints();

        // 提示建造狙击手
        var brk = r.GetMyFirstUnitByType("Barrack");
        g.ToClick(UIManager.Instance.World2UI(brk.Pos), "建造一个<u>狙击手</u>，偷袭对方基地");
        yield return new ConditionWaiter(() =>
        {
            foreach (var ut in brk.UnitCosntructingWaitingList)
            {
                if (ut == "Ghost")
                    return true;
            }

            return false;
        });
        g.HideAllHints();

        yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("Ghost") != null);
        // 提示拖动操作
        var cc = r.GetUnitsByType("CommanderCenter", 1)[0];
        var gh = r.GetMyFirstUnitByType("Ghost");
        g.ToDrag("拖动单位，使其单独行动",
            UIManager.Instance.World2UI(gh.Pos),
            UIManager.Instance.World2UI(r.MapSize / 2 + new Vec2(200, 0)),
            UIManager.Instance.World2UI(cc.Pos + new Vec2(200, 200)),
            UIManager.Instance.World2UI(cc.Pos));
        yield return new ConditionWaiter(() =>
        {
            gh = r.GetMyFirstUnitByType("Ghost");
            return gh != null && gh.MovePath.Count > 0 && gh.IgnoreTargetWhenMoving;
        });
        g.HideAllHints();
    }

    // PVE003 拖动操作教学
    static IEnumerator PVE003GuideImpl(Room4Client r)
    {
        var g = UIManager.Instance.Guide;

        yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("Tank") != null);
        yield return new TimeWaiter(1000);
        g.ToClick(UIManager.Instance.World2UI(r.GetMyFirstUnitByType("Tank").Pos),
            "小诺给我们送来了<u>坦克</u>");
        yield return new TimeWaiter(2000);

        g.ToDrag("<op>拖动</op>释放<u>雷达</u>",
            UIManager.Instance.World2UI(r.GetMyFirstUnitByType("CommanderCenter").Pos),
            UIManager.Instance.World2UI(r.MapSize - r.GetMyFirstUnitByType("CommanderCenter").Pos));

        yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("RadarSign") != null);
        g.HideAllHints();

        g.ToClick(UIManager.Instance.World2UI(new Vec2(r.MapSize.x / 2, 200)),
            "对方正在建造防御炮台");
        yield return new TimeWaiter(2000);
        g.HideAllHints();

        g.ToClick(UIManager.Instance.World2UI(r.GetMyFirstUnitByType("Airport").Pos),
            "建造<u>女妖</u>对抗炮台很有效");
        yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("Airport").UnitCosntructingWaitingList.Count > 0
            && r.GetMyFirstUnitByType("Airport").UnitCosntructingWaitingList.IndexOf("Banshee") >= 0);
        g.HideAllHints();

        yield return new ConditionWaiter(() => r.GetMyFirstUnitByType("Banshee") != null);
        g.ToClick(UIManager.Instance.World2UI(new Vec2(30, r.MapSize.y - 20)), "全体反击");
        yield return new TimeWaiter(3000);
        g.HideAllHints();
    }
}
